package cn.topevery.garden.wapi.controller;

import cn.topevery.garden.dal.logic.CarLogic;
import cn.topevery.garden.dal.logic.GpsClientStateLogic;
import cn.topevery.garden.dal.logic.PersonLogic;
import cn.topevery.garden.dal.util.PointUtils;
import cn.topevery.garden.entity.dto.GpsClientStateDTO;
import cn.topevery.garden.entity.po.GpsClientState;
import cn.topevery.garden.entity.query.GpsClientStateQuery;
import cn.topevery.garden.entity.vo.CarVO;
import cn.topevery.garden.entity.vo.GpsClientStateVO;
import cn.topevery.garden.entity.vo.PersonVO;
import cn.topevery.garden.framework.util.DateTimeUtil;
import com.github.dozermapper.core.Mapper;
import hw.topevery.framework.db.entity.DataPager;
import hw.topevery.framework.dto.PointDto;
import hw.topevery.framework.map.CoordinateTransHelper;
import hw.topevery.framework.util.ExcelUtil;
import hw.topevery.framework.web.JsonResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.sql.Timestamp;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 状态详情
 *
 * @author code-generate
 * @date 2021-09-13
 */
@Api(tags = "状态详情")
@RestController
@RequestMapping("/gpsClientState")
public class GpsClientStateController extends BaseController {

    @Autowired
    private Mapper mapper;

    @Autowired
    GpsClientStateLogic gpsClientStateLogic;

    @Autowired
    private PersonLogic personLogic;

    @Autowired
    private CarLogic carLogic;


    /**
     * 获取状态详情分页列表
     *
     * @param query
     * @return
     */
    @ApiOperation(value = "获取状态详情页列表")
    @PostMapping("/listPage")
    public JsonResult<DataPager<GpsClientStateVO>> listPage(@RequestBody GpsClientStateQuery query) {
        return JsonResult.ok(gpsClientStateLogic.listPage(query));
    }

    @ApiOperation("新增/编辑 状态详情信息")
    @PostMapping("/saveOrUpdate")
    public JsonResult<Boolean> saveOrUpdate(@Valid @RequestBody GpsClientStateDTO dto) {
        gpsClientStateLogic.saveOrUpdate(getUser().userId,mapper.map(dto, GpsClientState.class));
        return JsonResult.ok(true);
    }

    @ApiOperation("根据自增ID批量删除")
    @PostMapping("/deleteBatchById")
    public JsonResult<Boolean> deleteBatchById(@RequestBody Integer[] ids) {
        gpsClientStateLogic.deleteBatchById(getUser().userId,ids);
        return JsonResult.ok(true);
    }

    @ApiOperation("导出状态详情信息")
    @GetMapping("/export")
    public void export(GpsClientStateQuery query, HttpServletResponse response) {
        List<GpsClientStateVO> list = gpsClientStateLogic.listPage(query).records;
        ExcelUtil.exportExcel(list, "状态详情", "sheet1", GpsClientStateVO.class, "状态详情", response);
    }

    @ApiOperation("当前状态坐标点")
    @PostMapping("/getObjCurrentPos")
    public JsonResult<?> getObjCurrentPos(@RequestBody GpsClientStateQuery query) {
        List<Map<String, Object>> data = gpsClientStateLogic.getObjCurrentPos(query);
        Map<String, Object> res = new HashMap<>();
        if(data.size()>0){
            data.forEach(item->{
                if(query.getObjType() == 0) {
                    PersonVO PersonInfo = personLogic.getByUserId(query.getObjId());
                    res.put("type", PersonInfo.getTypeName());
//                    res.put("company", PersonInfo.get());
                }
                else{
                    CarVO CarInfo = carLogic.getByCarId(query.getObjId());
                    res.put("type", CarInfo.getTypeName());
//                    res.put("company", CarInfo.getCompanyName());
                }
                res.put("Id",item.get("c_id"));
                res.put("AccessType", query.getObjType());
                res.put("Code",item.get("c_name"));
                res.put("IconType",item.get("c_icon_type"));
                res.put("ClientKey",item.get("c_client_key"));
                res.put("ObjType",item.get("c_type"));
                res.put("Lng",item.get("c_geo_x"));
                res.put("Lat",item.get("c_geo_y"));


            });
        }

        return  JsonResult.ok(res);
    }

    @ApiOperation(value = "获取片区范围")
    @PostMapping(value = "/getExtentArea")
    public JsonResult<?> getExtentArea(@RequestBody GpsClientStateQuery query) {
        return JsonResult.ok(gpsClientStateLogic.getExtentByTypeAndId(query));
    }

    @ApiOperation(value = "获取轨迹信息")
    @PostMapping(value = "/getGpsTrace")
    public JsonResult<?> getGpsTrace(@RequestBody GpsClientStateQuery para) {
        Map<String, Object> res =  new HashMap<>();
        Map<String, Object> data = new HashMap<>();
        if( para.getObjType() == 3){
            data = gpsClientStateLogic.getSprinklerGpsTrace(para);
        }
        else {
            data = gpsClientStateLogic.getGpsTrace(para);
        }
        int needNextRequest = 0;
        List<Map<String, Object>> gpsPosList = new ArrayList<Map<String, Object>>();
        int gpsLength = 0;
        List<Map<String, Object>> Traces =  (List<Map<String, Object>>) data.get("Traces");
        Map<String, Object> lastStopPos = new HashMap<>();
        Map<String, Object> prev = new HashMap<>();
        for(int i =0;i<Traces.size();i++){
            Map<String, Object> record = Traces.get(i);
//        Traces.forEach(record->{
            Map<String, Object> pos = new HashMap<>();
            pos.put("InUseWaterRatio",data.get("InUseWaterRatio"));
            pos.put("OutUseWaterRatio",data.get("OutUseWaterRatio"));
            pos.put("Direction",record.get("c_degree"));
            pos.put("Speed",record.get("c_speed"));

            //坐标类型处理
            if(para.getPointType().equals(0)) {
                pos.put("Lng", record.get("c_long"));
                pos.put("Lat", record.get("c_lat"));
            }
            else if(para.getPointType().equals(1)){
               PointDto pointDto= CoordinateTransHelper.bd09WGS84(Double.parseDouble(record.get("c_long").toString()),Double.parseDouble(record.get("c_lat").toString()));
                pos.put("Lng", pointDto.getLng());
                pos.put("Lat", pointDto.getLat());
            }

            if( para.getObjType() == 3){
                pos.put("WaterLevel",record.get("c_water_level"));
            }
            pos.put("PointDistance",record.get("c_last_point_distance"));
            pos.put("GpsTime",record.get("c_gps_date"));
//            pos.put("GpsTimeStr", timeLogic.DateFormatter( ((Timestamp)record.get("c_gps_date")).toLocalDateTime()));
            pos.put("LastGpsTime",record.get("c_last_gps_date"));

            pos.put("LngLat",  pos.get("Lng")+","+pos.get("Lat"));
            pos.put("AccOn",record.get("c_acc_state"));
            pos.put("WorkStartTime",record.get("c_work_start_time"));
            pos.put("WorkIsValid",record.get("c_work_is_valid"));
            pos.put("CarWorkStatus",record.get("c_car_work_status"));
            pos.put("IsWorkLine",record.get("c_is_work_line"));

            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime gpstime=(LocalDateTime)record.get("c_gps_date");
            pos.put("GpsTimeStr",dateTimeFormatter.format(gpstime));
            if(Math.abs((int)pos.get("Speed"))<=0){
                pos.put("PointType",1);
            }
            else {
                pos.put("PointType",0);
            }
            if((int)pos.get("PointType")==1){
                if(lastStopPos==null)
                {
                    lastStopPos = pos;
                }
            }
            else {
                if(lastStopPos.size()>0){
//                    if(lastStopPos.get("GpsTime").equals(pos.get("GpsTime"))){
//
//                    }
                    lastStopPos.put("StopTimes", DateTimeUtil.GetTimeSpan(((Timestamp) lastStopPos.get("GpsTime")).toLocalDateTime(),((Timestamp) pos.get("GpsTime")).toLocalDateTime()));
                    lastStopPos.put("Second", Duration.between(((Timestamp) lastStopPos.get("GpsTime")).toLocalDateTime(),((Timestamp) pos.get("GpsTime")).toLocalDateTime()).toMillis()*1000);
//                    lastStopPos =null;

                }

            }
            if (i > 0) {
                prev = ((List<Map<String, Object>>)gpsPosList.get(0).get("GpsPoints")).get(((List<Map<String, Object>>)gpsPosList.get(0).get("GpsPoints")).size() - 1);
                double distance = 0;
                if (pos.get("Lng") != null && pos.get("Lat") != null && prev.get("Lng") != null && prev.get("Lat") != null) {
                    distance = PointUtils.countDistance(Double.parseDouble(pos.get("Lng").toString()), Double.parseDouble(pos.get("Lat").toString()),
                            Double.parseDouble(prev.get("Lng").toString()), Double.parseDouble(prev.get("Lat").toString()));
                }
                if (i < Traces.size()-1){
                    if (distance > 300 || distance==0) {
                        continue;
                    }
                }

            }
            if(gpsPosList.size()==0)
            {
//                List<Map<String, Object>> GpsTraceLine = new ArrayList<Map<String, Object>>();
                Map<String, Object> GpsPosition = new HashMap<>();
                GpsPosition.put("uId",para.getObjId());
                GpsPosition.put("StartDate",pos.get("GpsTimeStr"));
                GpsPosition.put("GpsPoints",new ArrayList<Map<String,Object>>());
                gpsPosList.add(GpsPosition);


                ((List<Map<String, Object>>)gpsPosList.get(0).get("GpsPoints")).add(pos);
            }
            else {
                Map<String, Object>  curGpsPos = gpsPosList.get(gpsPosList.size()-1);
                List<Map<String, Object>> curGpsPosList = (List<Map<String, Object>>) curGpsPos.get("GpsPoints");
                if(curGpsPosList.size()==0)
                {
                    curGpsPosList.add(pos);
                    curGpsPos.put("WorkStatus",(int)pos.get("IsWorkLine")==1?"是":"否");
                    curGpsPos.put("WarningName",(int)pos.get("CarWorkStatus")==1?"车辆超速":"无");

                }
                else {
                    Map<String, Object>   preGpsPos = curGpsPosList.get(curGpsPosList.size()-1);
                        curGpsPosList.add(pos);
                }



            }
            ++needNextRequest;
            gpsLength++;
            res.put("NeedRequest",false);





        };
        if(gpsPosList.size()>=1){
            res.put("CarGpsPoints",gpsPosList);
            Map<String, Object> lastLing = gpsPosList.get(gpsPosList.size()-1);
            if(lastLing.get("EndDate")==null){
                Map<String, Object> lastPostion =((List<Map<String, Object>>)lastLing.get("GpsPoints")).get(((List<Map<String, Object>>)lastLing.get("GpsPoints")).size()-1);
                lastLing.put("WorkTime",DateTimeUtil.GetTimeSpan((LocalDateTime)((List<Map<String, Object>>) lastLing.get("GpsPoints")).get(0).get("GpsTime"),(LocalDateTime)lastPostion.get("GpsTime")));
                lastLing.put("EndDate",lastPostion.get("GpsTimeStr"));
            }
        }
        res.put("Id",para.getObjId());






        return JsonResult.ok(res);
    }

}
